package com.mcxx.modules.temporary.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.mcxx.common.exception.BizException;
import com.mcxx.constant.MQConstant;
import com.mcxx.modules.minimumliving.service.ScheduleCheckService;
import com.mcxx.modules.temporary.service.TempNoticeBoardService;
import com.mcxx.modules.base.service.read.ActivitiReadService;
import com.mcxx.modules.miniSalvation.order.dto.NoticeBoardDTO;
import com.mcxx.modules.miniSalvation.order.dto.NoticeBoardDetailDTO;
import com.mcxx.modules.miniSalvation.order.dto.OrderDTO;
import com.mcxx.modules.miniSalvation.order.dto.OrderListForChoiceDTO;
import com.mcxx.modules.miniSalvation.order.entity.NoticeBoardDetailEntity;
import com.mcxx.modules.miniSalvation.order.entity.OrderDetailEntity;
import com.mcxx.modules.miniSalvation.order.entity.OrderStateEntity;
import com.mcxx.modules.miniSalvation.order.param.ActivitiParam;
import com.mcxx.modules.miniSalvation.order.param.OrderListSearchParam;
import com.mcxx.modules.miniSalvation.order.service.read.NoticeBoardDetailReadService;
import com.mcxx.modules.miniSalvation.order.service.read.NoticeBoardReadService;
import com.mcxx.modules.miniSalvation.order.service.write.NoticeBoardDetailWriteService;
import com.mcxx.modules.miniSalvation.order.service.write.NoticeBoardWriteService;
import com.mcxx.modules.miniSalvation.order.service.write.OrderDetailWriteService;
import com.mcxx.modules.system.dto.MQMessageDTO;
import com.mcxx.modules.temporary.fundpay.service.read.TmpFundPayReadService;
import com.mcxx.modules.temporary.order.dto.TmpOrderDTO;
import com.mcxx.modules.temporary.order.entity.TmpOrderCertEntity;
import com.mcxx.modules.temporary.order.service.read.TmpOrderCertReadService;
import com.mcxx.modules.temporary.order.service.read.TmpOrderReadService;
import com.mcxx.modules.temporary.order.service.write.TmpOrderWriteService;
import com.mcxx.util.BatchNoUtil;
import com.mcxx.util.Constant;
import com.mcxx.util.DateUtil;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.service.BaseService;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.mcxx.redis.client.RedisClusterUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@TaTransactional
public class TempNoticeBoardServiceImpl extends BaseService implements TempNoticeBoardService {

    @Autowired
    private NoticeBoardWriteService noticeBoardWriteService;
    @Autowired
    private NoticeBoardReadService noticeBoardReadService;
    @Autowired
    private TmpOrderReadService tmpOrderReadService;
    @Autowired
    private TmpOrderWriteService tmpOrderWriteService;
    @Autowired
    private NoticeBoardDetailReadService noticeBoardDetailReadService;
    @Autowired
    private NoticeBoardDetailWriteService noticeBoardDetailWriteService;
    @Autowired
    private ActivitiReadService activitiReadService;
    @Autowired
    private OrderDetailWriteService orderDetailWriteService;
    @Autowired
    private RedisClusterUtils redisClusterUtils;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private TmpFundPayReadService tmpFundPayReadService;
    @Autowired
    private TmpOrderCertReadService tmpOrderCertReadService;
    @Autowired
    private ScheduleCheckService scheduleCheckService;

    
    @Override
    public boolean changeDtoToEntity(NoticeBoardDTO noticeBoard, UserAccountVo userAccountVo){
        try{


            String batchNo = BatchNoUtil.getBatch(Constant.BusiCode.NOTICE_BOARD_BATCH,  noticeBoard.getAreaCode());
            noticeBoard.setBatchNo(batchNo);
            boolean rst = noticeBoardWriteService.addNoticeBoard(noticeBoard, userAccountVo);
            if(!rst){
                throw new BizException("-1", "创建公示异常");
            }
            if(Constant.PayWay.ALL.equals(noticeBoard.getPayWay())){
                noticeBoard.setPayWay("");
            }

            String redisKey = userAccountVo.getAreaCode()+noticeBoard.getBatchId()+noticeBoard.getPayWay();
            if(Constant.UserLevel.COUNTY.equals(userAccountVo.getAreaLevel())){

                redisKey = noticeBoard.getAreaCode()+noticeBoard.getBatchId()+noticeBoard.getPayWay();
            }
            List<NoticeBoardDetailEntity> noticeBoardDetailList = new ArrayList<>();
            Map<String, OrderListForChoiceDTO> map = redisClusterUtils.hmget(redisKey);
            if(null != map){

                if(null != map){
                    map.values().forEach(value -> {
                        OrderListForChoiceDTO dto = value;
                        NoticeBoardDetailEntity entity = new NoticeBoardDetailEntity();
                        BeanUtils.copyProperties(dto, entity);
                        entity.setBatchId(noticeBoard.getBatchId());
                        entity.setId(Constant.getUUID());
                        entity.setUserAreaLevel(userAccountVo.getAreaLevel());
                        entity.setIsObjection("1");
                        entity.setCheckResult("1");
                        String saveDate = dto.getStartMonth();
                        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
                        Date date = DateUtil.str2Date(saveDate, sdf2);
                        entity.setSaveDate(date);
                        entity.setRemark("");
                        noticeBoardDetailList.add(entity);
                    });
                }
            }
            if(CollectionUtils.isNotEmpty(noticeBoardDetailList)){

                int i = this.saveBatchObject(noticeBoardDetailList, noticeBoard.getUserAreaLevel());
                if(i>0){
                    return true;
                }
            }else{
                return true;
            }
            return false;
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }
    private static boolean checkValue(String e, List<String> orderIdList) {
        for (String s : orderIdList){
            if(e.equals(s)){
                return false;
            }
        }
        return true;
    }

    
    @Override
    public int saveBatchObject(List<NoticeBoardDetailEntity> noticeBoardDetailList, String userAreaLevel){

        List<String> orderIdList = new ArrayList<>();
        for (NoticeBoardDetailEntity entity: noticeBoardDetailList) {
            orderIdList.add(entity.getOrderId());
            entity.setUserAreaLevel(userAreaLevel);
            entity.setId(Constant.getUUID());
        }

        List<TmpOrderDTO> orderDTOList = tmpOrderReadService.getStateAndVersions(orderIdList);


        int rst = noticeBoardDetailWriteService.insertObject(noticeBoardDetailList);
        if(rst <= 0){
            throw new BizException("-1", "将业务添加到公示异常");
        }


        this.updateOrderStateForSaveObject(orderDTOList,null, userAreaLevel,1);


        return 1;
    }

    
    public void updateOrderStateForSaveObject(List<TmpOrderDTO> orderDTOList, List<String> orderIdList, String userAreaLevel, int excuType){
        String bizState = "";
        String preBizState = "";
        switch (excuType){
            case 1:

                bizState = Constant.UserLevel.STREET.equals(userAreaLevel) ? Constant.BizStateTmpNew.NOTICE_BOARD_CONFIRM : Constant.BizStateTmpNew.COUNTY_NOTICE_BOARD_CONFIRM;
                preBizState = bizState;
                break;
            case 2:

                bizState = Constant.UserLevel.STREET.equals(userAreaLevel) ? Constant.BizStateTmpNew.WAIT_NOTICE_BOARD : Constant.BizStateTmpNew.COUNTY_WAIT_NOTICE_BOARD;
                preBizState = Constant.UserLevel.STREET.equals(userAreaLevel) ? Constant.BizStateTmpNew.NOTICE_BOARD_CONFIRM : Constant.BizStateTmpNew.COUNTY_NOTICE_BOARD_CONFIRM;

                orderDTOList = tmpOrderReadService.getStateAndVersions(orderIdList);
                break;
        }

        tmpOrderWriteService.updateOrderState(orderDTOList, bizState, preBizState);
    }


    
    @Override
    public Map<String, List<String>> confirmBatch(List<String> batchNoList, String userAreaLevel){

        List<String> stateList = new ArrayList<String>(){{add(Constant.NoticeBoardState.WAIT); add(Constant.NoticeBoardState.REVOKE);}};
        Map<String, List<String>> rstMap = noticeBoardReadService.getBatchNoByStateStartDate(batchNoList, stateList, "Y");
        if(rstMap.containsKey("yesOperation") == false){
            return rstMap;
        }


        rstMap.putAll(noticeBoardDetailReadService.getNoByNoAndFamilyNums(rstMap.get("yesOperation")));
        if(rstMap.containsKey("yesObject") == false){
            return rstMap;
        }


        int rst = noticeBoardWriteService.updateStatusByBatchNos(rstMap.get("yesObject"), Constant.NoticeBoardState.ING,
                                                                null);
        if(rst <= 0){

            rstMap.put("fail", rstMap.get("yesObject"));
            return rstMap;
        }


        this.updateOrderStateByConfirm(batchNoList, userAreaLevel);

        rstMap.put("success", rstMap.get("yesObject"));
        return rstMap;
    }

    @Override
    public Map<String, List<String>> finishBatch(List<NoticeBoardDetailEntity> batchNoList, UserAccountVo userAccountVo,
                                                 String batchId, String finishRemark) {

        Map<String, List<String>> rstMap = new HashMap<>();
        List<String> ls = new ArrayList<>();
        ls.add(batchId);
        NoticeBoardDTO noticeBoardDTO = noticeBoardReadService.queryByBatchId(batchId);
        if(Constant.NoticeBoardState.ING.equals(noticeBoardDTO.getState().toString())){
            rstMap.put("yesOperation",ls);
        }else{
            rstMap.put("noOperation", ls);
        }
        if(!rstMap.containsKey("yesOperation")){
            return rstMap;
        }


        int rst = noticeBoardWriteService.updateStatusByBatchNos(rstMap.get("yesOperation"),
                                                            Constant.NoticeBoardState.COMPLETE, finishRemark);
        if(rst <= 0){

            rstMap.put("fail", rstMap.get("yesOperation"));
            return rstMap;
        }


        this.updateOrderStateByFinish(rstMap.get("yesOperation"), userAccountVo,batchNoList);



//        int rst = tmpFundPayReadService.verifyFunPay(, orderDTO.getAreaCode(),orderApproveDTO.getRescueYears(), null);





//        rst = tmpFamilyMainHistoryWriteService.backHistory(orderApproveDTO.getOrderId(), orderDTO.getFamilyId(), orderApproveDTO.getRescueYears(), orderApproveDTO.getSalvationNo(), userAccountVo);

//            log.info("{}", orderDTO.getId());




//        if("1".equals(orderApproveDTO.getApprovalResult())) {

//            rst = tmpFamilySalaryWriteService.updateStartDate(orderApproveDTO.getOrderId(), orderApproveDTO.getRescueYears());




//            rst = tmpOrderWriteService.updateStartDate(orderApproveDTO.getOrderId(), orderApproveDTO.getRescueYears());






        rstMap.put("success", rstMap.get("yesOperation"));


        return rstMap;
    }
    
    public void updateOrderStateByFinish(List<String> batchNoList, UserAccountVo userAccountVo,List<NoticeBoardDetailEntity> singel){

        String bizState = Constant.BizStateTmp.APPROVE_YES;
        if(Constant.UserLevel.COUNTY.equals(userAccountVo.getAreaLevel())){

            bizState = Constant.BizStateTmp.APPROVE_YES;
        }
        if(CollectionUtils.isNotEmpty(singel)){
            List<OrderDTO> orderDTOList = noticeBoardDetailReadService.getOrderStateAndVersions(batchNoList,"BCX56");
            List<OrderDTO> singelOrder = new ArrayList<>();
            for(NoticeBoardDetailEntity en : singel){
                for(int i = 0 ; i < orderDTOList.size(); i++){
                    OrderDTO orderDTO = orderDTOList.get(i);
                    if(Constant.BizStateTmp.APPROVE_REJECT.equals(orderDTO.getState())){

                        continue;
                    }

                    if(en.getOrderId().equals(orderDTO.getId())){

                        ActivitiParam activitiParam = new ActivitiParam(orderDTO.getBizState(), en.getCheckResult(), orderDTO.getSalvMoney(),Constant.BusinessCode.LINSHI);
                        String nextActviti = activitiReadService.getOrderNextActviti(activitiParam, userAccountVo.getRoles());
                        if("-1".equals(nextActviti)){
                            throw new BizException("-1", "账号没有保存审核信息的信息");
                        }
                        orderDTO.setBizState(nextActviti);
                        orderDTO.setReason(en.getRemark());
                        singelOrder.add(orderDTO);
                        orderDTOList.remove(i);
                        break;
                    }
                }
            }
            if(CollectionUtils.isNotEmpty(singelOrder)){

                List<OrderDetailEntity> detailList = new ArrayList<>();
                OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
                orderDetailEntity.setCheckDate(new Date());
                orderDetailEntity.setOperator(userAccountVo.getUsername());
                orderDetailEntity.setCreateBy(userAccountVo.getUserId());
                orderDetailEntity.setOrgId(userAccountVo.getOrgId());

                orderDetailEntity.setBusinessStatus(Constant.RemarkOperType.STREET);

                orderDetailEntity.setCheckType(Constant.CheckDatailStatus.NOTICE_he);

                if(Constant.UserLevel.COUNTY.equals(userAccountVo.getAreaLevel())){

                    orderDetailEntity.setBusinessStatus(Constant.RemarkOperType.COUNTY);
                    orderDetailEntity.setCheckType(Constant.CheckDatailStatus.NOTICE_Pi);
                }

                for(OrderDTO orderDTO:singelOrder){
                    bizState = orderDTO.getBizState();
                    OrderStateEntity orderStateEntity = new OrderStateEntity(orderDTO.getId(), bizState, bizState, orderDTO.getVersion());
                    int cnt = tmpOrderWriteService.updateState(orderStateEntity);
                    if(cnt <= 0){
                        throw new BizException("-1", "修改业务的状态异常");
                    }
                    orderDetailEntity.setCheckResult(bizState);
                    orderDetailEntity.setCheckOpinion(orderDTO.getReson());
                    detailList.add(orderDetailEntity);
                }
                this.addOrderDetails(detailList);
            }
        }else{
            this.updateOrderState(batchNoList, bizState, bizState,userAccountVo);
        }

    }

    
    public void updateOrderStateByConfirm(List<String> batchNoList, String userAreaLevel){

        String bizState = Constant.UserLevel.STREET.equals(userAreaLevel) ? Constant.BizStateTmp.NOTICE_BOARD_ING : Constant.BizStateTmp.COUNTY_NOTICE_BOARD_ING;
        this.updateOrderState(batchNoList, bizState, bizState,null);
    }

    
    public void addOrderDetails(List<OrderDetailEntity> detailList){
        if(CollectionUtils.isNotEmpty(detailList)){

            int rst = orderDetailWriteService.insertSalvationAudits(detailList);
            if(rst <= 0){
                throw new BizException("-1", "保存公示审核意见异常");
            }
        }
    }
    
    public void updateOrderState(List<String> batchNoList, String bizState, String preBizState, UserAccountVo userAccountVo){
        List<OrderDTO> orderDTOList = noticeBoardDetailReadService.getOrderStateAndVersions(batchNoList,"BCX56");

        if(null != userAccountVo){
            List<OrderDetailEntity> detailList = new ArrayList<>();
            OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
            orderDetailEntity.setCheckDate(new Date());
            orderDetailEntity.setOperator(userAccountVo.getUsername());
            orderDetailEntity.setCreateBy(userAccountVo.getUserId());
            orderDetailEntity.setOrgId(userAccountVo.getOrgId());

            orderDetailEntity.setBusinessStatus(Constant.RemarkOperType.STREET);

            orderDetailEntity.setCheckType(Constant.CheckDatailStatus.NOTICE_he);

            if(Constant.UserLevel.COUNTY.equals(userAccountVo.getAreaLevel())){

                orderDetailEntity.setBusinessStatus(Constant.RemarkOperType.COUNTY);
                orderDetailEntity.setCheckType(Constant.CheckDatailStatus.NOTICE_Pi);
            }

            for(OrderDTO orderDTO : orderDTOList){
                if(Constant.BizStateTmp.APPROVE_REJECT.equals(orderDTO.getState())){

                    continue;
                }
                OrderStateEntity orderStateEntity = new OrderStateEntity(orderDTO.getId(), bizState, preBizState, orderDTO.getVersion());
                int cnt = tmpOrderWriteService.updateState(orderStateEntity);
                if(cnt <= 0){
                    throw new BizException("-1", "修改业务的状态异常");
                }
                orderDetailEntity.setCheckResult("1");
                orderDetailEntity.setCheckOpinion("");
                detailList.add(orderDetailEntity);
            }
            this.addOrderDetails(detailList);
        }else{
            for(OrderDTO orderDTO : orderDTOList){
                if(Constant.BizStateTmp.APPROVE_REJECT.equals(orderDTO.getState())){

                    continue;
                }
                OrderStateEntity orderStateEntity = new OrderStateEntity(orderDTO.getId(), bizState, preBizState, orderDTO.getVersion());
                int cnt = tmpOrderWriteService.updateState(orderStateEntity);
                if(cnt <= 0){
                    throw new BizException("-1", "修改业务的状态异常");
                }
            }
        }
    }

    
    @Override
    public Map<String, List<String>> deleteBatch(List<String> batchNoList, UserAccountVo userAccountVo){

        List<String> stateList = new ArrayList<String>(){{add(Constant.NoticeBoardState.WAIT); add(Constant.NoticeBoardState.REVOKE);}};
        Map<String, List<String>> rstMap = noticeBoardReadService.getBatchNoByStateStartDate(batchNoList, stateList, "Y");
        if(rstMap.containsKey("yesOperation") == false){

            return rstMap;
        }
        List<TmpOrderDTO> orderDTOList = new ArrayList<>();
        List<OrderDTO> orderDTOS = noticeBoardDetailReadService.getOrderStateAndVersions(rstMap.get("yesOperation"),"BCX56");
        List<String> stIdList1 = orderDTOS.stream().map(OrderDTO::getId).collect(Collectors.toList());

        this.updateOrderStateForSaveObject(orderDTOList,stIdList1, userAccountVo.getAreaLevel(),2);


        int rst = noticeBoardWriteService.deleteBatch(rstMap.get("yesOperation"));
        if(rst <= 0){
            rstMap.put("success", rstMap.get("yesOperation"));
        }


        rstMap.put("success", rstMap.get("yesOperation"));
        return rstMap;
    }
    
    @Override
    public Boolean deleteRedisKey(String batchId){
        if(StringUtils.isEmpty(batchId)){
            return true;
        }
        int res = 0;
        Set<String> batchKeys = redisClusterUtils.hasKeys(batchId);
        if(CollectionUtils.isNotEmpty(batchKeys)){
            for (String key : batchKeys){
                res += redisClusterUtils.del(key);
            }
        }
        if(res > 0){
            return true;
        }
        return false;
    }

    
    @Override
    public void sendRabbitMQToFinish(List<NoticeBoardDetailEntity> changeData,String batchId, String finishRemark,
                                     UserAccountVo userAccountVo){

        NoticeBoardDTO noticeBoardDTO = noticeBoardReadService.queryByBatchId(batchId);

        if(null == noticeBoardDTO){
            throw  new BizException("-1","批次号:{"+noticeBoardDTO.getBatchNo()+"},不存在，请确认");
        }


        if(!Constant.NoticeBoardState.ING.equals(noticeBoardDTO.getState().toString())){
            throw  new BizException("-1","批次号:{"+noticeBoardDTO.getBatchNo()+"},状态为{"+noticeBoardDTO.getState()+"}  状态不是公式中。不能结束公示");
        }

        tmpFundPayReadService.verifyFunPay(noticeBoardDTO.getAreaCode(), DateUtil.getMonthString(),noticeBoardDTO.getPayWay());


        List<TmpOrderCertEntity> noticeBoardDTOList = tmpOrderCertReadService.cntNoticeCertNum(new ArrayList<String>(new ArrayList<String>(){{add(noticeBoardDTO.getBatchNo());}}));
        if(CollectionUtils.isEmpty(noticeBoardDTOList)){
            throw new BizException("-1","批次号:{"+noticeBoardDTO.getBatchNo()+"},没有上传公示照片，请上传后再进行提交确认");
        }
    }

    
    @Override
    public Map<String, Object> printNoticeBoardTown(OrderListSearchParam param){
        Map<String, Object> rstMap = new HashMap<>();

        NoticeBoardDTO noticeBoard = noticeBoardReadService.queryByBatchId(param.getBatchId());

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(noticeBoard.getStartDate());
        calendar.add(Calendar.DAY_OF_YEAR,6);
        noticeBoard.setEndDate(calendar.getTime());

        noticeBoard.setTimeLimit("7");

        rstMap.put("noticeBoard", noticeBoard);



        param.setTableOrder("BCX56");
        param.setTableFamily("BCF24");
        param.setTableMember("BCF23");
        List<NoticeBoardDetailDTO> noticeBoardDetailList = noticeBoardDetailReadService.queryObjectByBatchId(param);
        rstMap.put("noticeBoardDetailList", noticeBoardDetailList);
        NoticeBoardDetailDTO underAge = noticeBoardDetailReadService.queryTmpFinishedUnderAgeFamily(param);
        rstMap.put("underAgeFamilyNumber",underAge.getFamilyNumber());
        rstMap.put("underAgeFamilyCount",underAge.getFamilyCount());

        return rstMap;
    }
}
